package com.firefly.mobile.app.util;

import java.io.IOException;
import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

/**
 * 顺硕会员密码加密解密方法
 * @author Administrator
 *
 */
public class UserLoginUtil {

	private final static String DES = "DES";
	
	public static final int DEFINE_LENGTH 	= 15 ; // 密码总长度
	public static final int FIX_LENGTH 		= 2	 ; // 用来标记原始密码长度的字符串形式
	
	public static void main(String[] args) {
		String pwd = "111111";
		String key = "123456789012345678901234";
		String en = encrypt(pwd,key);
		// en = "72a18b68b5d200e240c47d28cedf2d1c";
		String de = decrypt(en,key);
		System.out.println("原始明文 pwd = "+pwd);
		System.out.println(en + " , "+en.length());
		System.out.println(de);
	}
	
	/**
	 * 顺硕会员的密码在传输过程必须先加密
	 * @param pwd 密码明文
	 * @param key 密钥
	 * @return
	 */
	public static String encrypt( String pwd , String key ){
		if( pwd == null ){
			return null;
		}
		String data = fillPWD( pwd );
		String result = null ;
		try {
			result = encryptDESString(data, key);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result ;
	}
	
	/**
	 * 密码解密
	 * @param pwd 密码密文
	 * @param key 密钥
	 * @return
	 */
	public static String decrypt( String pwd , String key){
		if( pwd == null ){
			return null;
		}
		try {
			String result = decryptDESString(pwd, key);
			String data = cutPWD( result );
			System.out.println("[解密内容]data = "+data);
			return data;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	private static String cutPWD(String pwd) {
		String sourceLength = pwd.substring(0,2);
		int length = string2Ing(sourceLength);
		String sourcePwd = pwd.substring(2,2+length);
		return sourcePwd;
	}

	private static String fillPWD(String pwd) {
		int length = pwd.length();
		if( length >= DEFINE_LENGTH ){
			throw new RuntimeException( "密码长度大于"+ DEFINE_LENGTH +"位" );
		}
		int addLength = DEFINE_LENGTH - FIX_LENGTH - length ;
		StringBuilder blank = new StringBuilder();
		for (int i = 0; i < addLength; i++) {
			blank.append("F");
		}
		pwd = int2String(length) + pwd + blank.toString();
		return pwd;
	}

	private static String int2String( int i){
		if( i > 0 && i < 10){
			return "0"+i;
		}else{
			return "" + i;
		}
	}
	
	private static int string2Ing( String s ){
		return Integer.valueOf(s);
	}
	
	/**
     * 单DES加密
     * @return byte[]
     */
    public static byte[] encryptDES(String data, String key) throws Exception {
        return encrypt(data.getBytes(), key.getBytes());
    }
    
    /**
     * 单DES加密
     * @return String （Base64）
     */
    public static String encryptDESString(String data, String key) throws Exception {
        byte[] bt = encryptDES(data, key);
        String strs = new String( ByteUtil.byte2hex(bt) );
        System.out.println(data+ " - "+strs + " - " + key );
        return strs;
    }

    /**
     * 单DES解密
     */
    public static byte[] decryptDES(String data, String key) throws IOException,
            Exception {
        if (data == null)
            return null;
        byte[] buf = ByteUtil.hex2byte( data );
        return decrypt(buf,key.getBytes());
    }
    
    /**
     * 单DES解密
     */
    public static String decryptDESString(String data, String key) throws IOException,
            Exception {
        if (data == null)
            return null;
        byte[] buf = decryptDES(data, key) ;
        return new String( buf );
    }

    /**
     * Description 根据键值进行加密
     * @param data
     * @param key  加密键byte数组
     * @return
     * @throws Exception
     */
    private static byte[] encrypt(byte[] data, byte[] key) throws Exception {
        // 生成一个可信任的随机数源
        SecureRandom sr = new SecureRandom();

        // 从原始密钥数据创建DESKeySpec对象
        DESKeySpec dks = new DESKeySpec(key);

        // 创建一个密钥工厂，然后用它把DESKeySpec转换成SecretKey对象
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
        SecretKey securekey = keyFactory.generateSecret(dks);

        // Cipher对象实际完成加密操作
        Cipher cipher = Cipher.getInstance(DES);

        // 用密钥初始化Cipher对象
        cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);

        return cipher.doFinal(data);
    }
    
    
    /**
     * Description 根据键值进行解密
     * @param data
     * @param key  加密键byte数组
     * @return
     * @throws Exception
     */
    private static byte[] decrypt(byte[] data, byte[] key) throws Exception {
        // 生成一个可信任的随机数源
        SecureRandom sr = new SecureRandom();

        // 从原始密钥数据创建DESKeySpec对象
        DESKeySpec dks = new DESKeySpec(key);

        // 创建一个密钥工厂，然后用它把DESKeySpec转换成SecretKey对象
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
        SecretKey securekey = keyFactory.generateSecret(dks);

        // Cipher对象实际完成解密操作
        Cipher cipher = Cipher.getInstance(DES);

        // 用密钥初始化Cipher对象
        cipher.init(Cipher.DECRYPT_MODE, securekey, sr);

        return cipher.doFinal(data);
    }
	
}
